package base

import (
	"fmt"
	"net/http"

	"gitee.com/zoneaurora/shop/internal/common"
	"gitee.com/zoneaurora/shop/internal/model"
	"gitee.com/zoneaurora/shop/internal/vo"
	"gorm.io/gorm"

	"github.com/gin-gonic/gin"
)

type IBaseLogic interface {
	Create(*gin.Context)
	Delete(*gin.Context)
	Update(*gin.Context)
	Select(*gin.Context)
	GetPageList(*gin.Context)
	Options(*gin.Context)
}

type BaseLogic[T model.Category |
	model.Order |
	model.Comment |
	model.Product |
	model.OrderItem |
	model.User |
	model.AdminUser] struct {
	DB *gorm.DB
}

func (b *BaseLogic[T]) Create(c *gin.Context) {
	//  获取请求参数
	var requestData T
	c.Bind(&requestData)

	if err := b.DB.Create(&requestData).Error; err != nil {
		common.JSON(c, http.StatusInternalServerError, "创建数据失败", nil)
		return
	}
	common.JSON(c, http.StatusOK, "创建数据成功", requestData)
}

func (b *BaseLogic[T]) Delete(c *gin.Context) {
	//  获取请求参数
	id := c.Param("id")

	var model T
	if err := b.DB.Delete(&model, id).Error; err != nil {
		common.JSON(c, http.StatusInternalServerError, "删除数据失败", nil)
		return
	}
	common.JSON(c, http.StatusOK, "删除数据成功", nil)
}

func (b *BaseLogic[T]) Update(c *gin.Context) {
	//  获取请求参数
	id := c.Param("id")
	var requestData T
	c.Bind(&requestData)

	var model T
	result := b.DB.First(&model, id).Updates(requestData)
	if result.Error != nil {
		common.JSON(c, http.StatusInternalServerError, "更新数据失败", nil)
		return
	}
	common.JSON(c, http.StatusOK, "更新数据成功", model)
}

func (b *BaseLogic[T]) Select(c *gin.Context) {
	//  获取请求参数
	id := c.Param("id")

	var model T
	if err := b.DB.First(&model, id).Error; err != nil {
		common.JSON(c, http.StatusInternalServerError, "查询数据失败", nil)
		return
	}
	common.JSON(c, http.StatusOK, "查询数据成功", model)
}

func (b *BaseLogic[T]) GetPageList(c *gin.Context) {
	//  获取请求参数
	var requestParam vo.Pagination
	c.Bind(&requestParam)
	if requestParam.Order != "asc" {
		requestParam.Order = "desc"
	}
	if requestParam.SortName == "" {
		requestParam.SortName = "updated_at"
	}
	order := fmt.Sprintf("%s %s", requestParam.SortName, requestParam.Order)

	var models []T
	var total int64
	res := b.DB.Find(&models)
	if res.Error != nil {
		common.JSON(c, http.StatusInternalServerError, "查询数据失败", nil)
		return
	}
	total = res.RowsAffected
	err := b.DB.Offset((requestParam.Page - 1) * requestParam.Size).
		Order(order).Limit(requestParam.Size).Find(&models).Error
	if err != nil {
		common.JSON(c, http.StatusInternalServerError, "查询数据失败", nil)
		return
	}
	common.JSON(c, http.StatusOK, "查询数据成功", gin.H{
		"list":  models,
		"total": total,
	})
}

func (b *BaseLogic[T]) Options(c *gin.Context) {
	var modelEntity T
	common.JSON(c, http.StatusOK, "查询数据成功", gin.H{
		"model":      modelEntity,
		"connection": nil,
	})
}
